local lanes = require "lanes"
local config = require "config"
local datasource = config.mysql.data
local username = config.mysql.user
local password = config.mysql.auth
local host = config.mysql.host
local port = config.mysql.port

local function execute(mysql, msg)
    local method = msg.method
    if not method then
        return
    end

    local param = string.split(msg.method, ".", 2)
    local ok, chunk = pcall(require, "data." .. param[1])
    if not ok then
        return
    end

    if #param == 1 then
        return mysql.execute(chunk, msg)
    end

    if type(chunk) ~= "table" then
        return
    end

    local func = chunk[param[2]]
    if not func then
        return
    end

    return mysql.execute(func, msg)
end

local function processor(linda, idx)
    local lanes = require "lanes"
    local mysql = require "utils.mysql"

    while true do
        if cancel_test() then
            return
        end

        local ok, failmsg = mysql.create(datasource, username, password, host, port)
        if ok then
            break
        end

        spdlog.error("mysql", "luasql_failmsg : " .. failmsg)
        lanes.sleep(3)
    end

    spdlog.debug("mysql", "database[%s:%s %s#%d] processor start ...", host, port, datasource, idx)
    while not cancel_test() do repeat
        local key, rpc = linda:receive(3.0, "database")
        if key ~= "database" then
            mysql.ping()
            break
        end

        local id, msg = table.unpack(rpc)
        if not id or not msg then
            break
        end

        local ok, result = execute(mysql, msg)

        if ok then
            linda:send("coroutine_resume", table.pack(id, ok, result))
        else
            linda:send("coroutine_resume", table.pack(id, false))
        end
    until true end

    mysql.destory()
    spdlog.debug("mysql", "database[%s:%s %s##%d] processor quit ...", host, port, datasource, idx)
end

-------------------------------------------------------------------------------
---! 启动接口
-------------------------------------------------------------------------------
register_post_init(function()
    for idx = 1, 8 do
        SERVICE_D:create("mysql", processor, idx)
    end
end)
